<template>
  <div style="width: 100%">
    <div style="display: flex; height: 600px;">
      <el-card shadow="hover" style="width: 20%; min-width: 260px; height: 600px;  background: #fff;overflow-y: auto;">
        <span class="bt"> <span class="block"></span> 巡视路线 </span>
        <el-radio-group v-model="selectedVideo.equipmentId">
          <el-tree
            ref="patrolRouteTreeRef"
            v-loading="patrolRouteLoading || patrolRecordLoading"
            node-key="id"
            :data="patrolRouteList"
            :props="{ label: 'label', children: 'children' }"
            :expand-on-click-node="false"
            style="min-width: 260px"
            default-expand-all
          >
            <template #default="{ node, data }">
              <template v-if="data.patrolRouteName">
                <svg-icon icon-class="camera-circle" style="font-size: 18px; position: relative; right: 7px;;" />
                <span style="display: inline-block; width: calc(100% - 90px); height: 26px; line-height: 26px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" >
                  <el-tooltip effect="dark" :content="data.patrolRouteName" placement="top" >
                    {{ data.patrolRouteName }}
                  </el-tooltip>
                </span>
              </template>
              <el-radio v-else :value="data.equipmentId" :disabled="data.deviceStatus=='OFFLINE'" @change="(flag)=> { selectPatrolRoute(data, flag) }">
                <span v-if="data.deviceStatus=='OFFLINE'" style="color: rgb(200 90 90);">（离线）</span>
                <span>{{ node.label }}</span>
              </el-radio>
            </template>
          </el-tree>
        </el-radio-group>
      </el-card>

      <el-card shadow="hover" style="width: calc(60% - 20px); min-width: 800px; height: 100%; margin: 0 10px; background: #fff">
        <span class="bt">  <span class="block"></span>  实时巡视视频 </span>
        <div v-loading="videoLoading" style="position: relative; height: calc(100% - 80px); background-color: #efefef">
          <VideoEasyPlayer v-if="selectedVideo.url" :id="selectedVideo.equipmentId" :url="selectedVideo.url" />
          <p v-if="selectedVideo.equipmentId == null" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)">请选择视频</p>
          <p v-if="selectedVideo.status == -1" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)">视频播放失败</p>
          <p v-if="videoLoading == false && selectedVideo.status != -1 && selectedVideo.equipmentId != null && selectedVideo.url == null" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)">
            点击开始播放
          </p>
        </div>
        <div style="height: 50px; display: flex; justify-content: center; align-items: center">
          <el-tag v-if="patrolTaskExecutor.status==1" type="success" style="margin-right: 10px;" >任务进行中</el-tag>
          <el-tag v-if="patrolTaskExecutor.status==2" type="primary" style="margin-right: 10px;">任务已完成</el-tag>
          <el-button v-if="patrolTaskExecutor.status==0" v-loading="startPatrolLoading" type="primary" @click="startPatrolTask">开始</el-button>
          <el-button type="primary" :disabled="videoList.filter((item: any) => item.deviceStatus === 'ONLINE').length <= 1" @click="nextVideo">
            下一个
          </el-button>
          <el-button v-loading="completeTaskLoading" type="primary" @click="completeTask">完成</el-button>
        </div>
      </el-card>

      <el-card shadow="hover" style="width: 20%; min-width: 320px; height: 100%; background: #fff">
        <span class="bt"> <span class="block"></span> 巡视事件 </span>
        <el-table v-loading="inspectionEventLoading" :data="inspectionEventList" border height="500">
          <el-table-column label="事件类型" align="center" prop="eventType">
            <template #default="scope">
              <dict-tag :options="event_type" :value="scope.row.eventType" />
            </template>
          </el-table-column>
          <el-table-column label="事件地点" align="center" prop="eventAddress" show-overflow-tooltip />
          <el-table-column label="抓拍照片" align="center" class-name="small-padding fixed-width">
            <template #default="scope">
              <span style="font-weight: 400; font-size: 14px; color: #0058f6; cursor: pointer" @click="openImgList(scope.row.imgUrlList)"> 查看 </span>
            </template>
          </el-table-column>
        </el-table>

        <el-button type="primary" style="width: 100%; margin-top: 10px" @click="openEventReport">事件上报</el-button>
      </el-card>
    </div>

    <el-card shadow="hover" style="height: 100%; background: #fff; margin-top: 10px; min-width: 1400px;">
      <span class="bt"> <span class="block"></span> 巡视记录 </span>
      <el-table v-loading="patrolRecordLoading" :data="patrolRecordList" height="400px" border>
        <el-table-column label="巡视设备名称" align="center" prop="equipmentName" min-width="120" show-overflow-tooltip />
        <el-table-column label="设备位置" align="center" min-width="200" show-overflow-tooltip>
          <template #default="scope">
            {{ getParkPositionStr(scope.row.parkBuildingName, scope.row.parkBuildingAreaName, scope.row.parkBuildingFloorName, scope.row.parkBuildingRoomName) }}
          </template>
        </el-table-column>
        <el-table-column label="巡视时长" align="center" min-width="120" show-overflow-tooltip >
          <template #default="scope">
            <span v-if="patrolTaskExecutor.status == 0" style="color: #d45b5b">
              点击开始后开始计时
            </span>
            <span v-else>
              {{ secondsToTime(scope.row.patrolDuration) }}
            </span>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-dialog v-model="showCheckIn" width="400" title="巡视任务打卡" append-to-body destroy-on-close :show-close="false">
      <div class="http-message">
        <p style="height: 30px; line-height: 30px">
          <label style="width: 100px; text-align: right; display: inline-block;">打卡时间：</label>{{ parseTime(new Date()) }}
        </p>
        <p style="height: 30px; line-height: 30px">
          <label style="width: 100px; text-align: right; display: inline-block;" >注意：</label>该窗口将在10分钟后关闭
        </p>
        <p style="display: flex; justify-content: center">
          <el-button v-loading="checkInLoading" :disabled="checkInLoading" type="primary" @click="checkIn">打卡</el-button>
        </p>
      </div>
    </el-dialog>

    <!--  上报事件  -->
    <el-dialog v-model="dialog.showEventReport" :title="dialog.title" width="600px" append-to-body destroy-on-close>
      <event-report :event-source="2" :equipment-id="selectedVideo.equipmentId" :equipment-name="selectedVideo.equipmentName" :business-id="props.cameraPatrolTaskExecutorId" business-type="1" @close="dialog.showEventReport = false" @submit="getInspectionEventList" />
    </el-dialog>

    <!-- 图片详情 -->
    <el-dialog v-model="dialog.showImgList" title="图片详情" width="1000" append-to-body destroy-on-close>
      <el-carousel v-if="imgList != null && imgList.length > 0" trigger="click" height="500px">
        <el-carousel-item v-for="item in imgList" :key="item">
          <el-image style="width: 1000px; height: 500px" :src="item.url"></el-image>
        </el-carousel-item>
      </el-carousel>
      <p v-else style="text-align: center;"> 无相关图片 </p>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { getCameraList, patrolTaskInfoLogStart, updatePatrolTaskExecutorClock } from '@/api/security/video-patrol/camera-patrol-task-executer'
import request from '@/utils/request'
import { listCommeneventrecord, listeventrecord } from '@/api/event/eventRecord/';
import EventReport from '@/views/security/video-monitor/real-time-monitor/components/EventReport.vue'
import { parseTime, secondsToTime } from '@/utils/dateTime'
import { getParkPositionStr } from '@/utils/parkUtil'
import { ElButton } from 'element-plus';
import mapNoticeStore from '@/store/modules/mapNotice';

const { proxy } = getCurrentInstance() as ComponentInternalInstance
const props = defineProps({
  cameraPatrolTaskExecutorId: {
    type: String,
    default: '',
    required: true
  }
})
const emit = defineEmits(['close', 'submit'])

const { event_type } = toRefs<any>(proxy?.useDict('ai_algorithm_type', 'alarm_type', 'event_type'))

const videoList = ref([])
const closeTimer = ref()
const timer = ref()
const patrolRouteTreeRef = ref()
//  选择的视频
const selectedVideo = ref<any>({
  startTime: undefined,
  endTime: undefined,
  patrolDuration: undefined,
  name: undefined,
  equipmentId: undefined,
  url: undefined
})
const dialog = reactive({
  showExecute: false,
  showEventReport: false,
  showImgList: false,
  title: ''
})

/**
 * 打开事件上报弹窗
 */
const openEventReport = async () => {
  if (selectedVideo.value.equipmentId) {
    dialog.showEventReport = true
    dialog.title = '事件上报'
  } else {
    proxy.$modal.msgWarning('请先选择左侧摄像头')
  }
}

/**
 * 获取巡视事件列表
 */
const inspectionEventList = ref([])
const inspectionEventLoading = ref(true)
const getInspectionEventList = async () => {
  inspectionEventLoading.value = true
  const param = { businessId: props.cameraPatrolTaskExecutorId, businessType: 1 }
  const res = await listCommeneventrecord(param).finally(() => {
    inspectionEventLoading.value = false
  })
  inspectionEventList.value = res.rows
}

/**
 * 获取巡视路线
 */
const patrolRouteLoading = ref(false)
const patrolRouteList = ref([])
const getPatrolRouteList = async (id: string) => {
  patrolRouteLoading.value = true
  const res = await request({ url: '/camera/patrolTaskExecutor/get-patrol-route/' + id, method: 'get' }).finally(() => { patrolRouteLoading.value = false })
  console.log('获取巡视路线：', res)

  res.data.forEach((patrolRoute: any) => {
    patrolRoute.id = patrolRoute.cameraPatrolRouteId
    patrolRoute.label = patrolRoute.patrolRouteName
    patrolRoute.children = patrolRoute.routeCameraList
    patrolRoute.children.forEach((camera: any) => {
      camera.id = camera.equipmentId
      camera.label = camera.equipmentName

      videoList.value.push(JSON.parse(JSON.stringify(camera)))
    })
  })

  patrolRouteList.value = res.data
}

/**
 * 获取巡视记录
 */
const patrolRecordLoading = ref(false)
let patrolRecordList = ref<any>([])
const getPatrolLogList = () => {
  patrolRecordLoading.value = true
  request({
    url: '/camera/patrolTaskInfoLog/list',
    method: 'get',
    params: { pageSize: 99999, cameraPatrolTaskExecutorId: props.cameraPatrolTaskExecutorId }
  }).then((res: any) => {
    console.log('获取巡视记录：', res)

    patrolRecordList.value = res.rows
  }).finally(() => { patrolRecordLoading.value = false })
}

/**
 * 开始巡视任务
 */
const startPatrolLoading = ref(false)
const startPatrolTask = async () => {
  if (selectedVideo.value.equipmentId) {
    startPatrolLoading.value = true
    const res = await patrolTaskInfoLogStart(props.cameraPatrolTaskExecutorId).finally(() => { startPatrolLoading.value = false })
    patrolTaskExecutor.value = res.data

    proxy?.$modal.msgSuccess('任务开始成功')

    // 10秒后提示打卡
    if (patrolTaskExecutor.value.clockFlag == 1 && patrolTaskExecutor.value.clockFlagStatus == 0) {
      setTimeout(() => {
        showCheckIn.value = true

        // 10分钟后关闭提示
        setTimeout(() => {
          showCheckIn.value = false
        }, 10 * 60 * 1000);
      }, 10 * 1000);
    }
  } else {
    proxy?.$modal.msgError('请先选择左侧摄像头再开始')
  }
}

/**
 * 选择巡视路线
 */
const selectPatrolRoute = (node: any, flag: any) => {
  console.log('选择巡视路线设备：', node)

  // 赋值当前节点
  selectedVideo.value = JSON.parse(JSON.stringify(node))

  // 添加巡视记录
  const currNodeCameraIndex = patrolRecordList.value.findIndex((item:any) => { return item.equipmentId == selectedVideo.value.equipmentId })
  if (currNodeCameraIndex == -1) {
    selectedVideo.value.startTime = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
    selectedVideo.value.endTime = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
    selectedVideo.value.patrolDuration = 0
    patrolRecordList.value.push(JSON.parse(JSON.stringify(selectedVideo.value)))
  }

  playVideo()
}

/**
 * 播放视频
 */
const videoLoading = ref(false)
const playVideo = () => {
  if (selectedVideo.value.equipmentId) {
    videoLoading.value = true
    request({
      url: '/equipment/equipment-info/get-video-url/' + selectedVideo.value.equipmentId,
      method: 'get',
      params: { playType: 0, playProtocol: 0 }
    }).then((videoRes) => {
      console.log('获取视频地址：', videoRes)

      if (videoRes.data && videoRes.data.media_url) {
        selectedVideo.value.url = JSON.parse(videoRes.data.media_url).wan
      } else {
        selectedVideo.value.status = -1
      }
    }).finally(() => {
      videoLoading.value = false
    })
  } else {
    proxy?.$modal.msgError('请先选择左侧摄像头再开始')
  }
}

/**
 * 下一个视频
 */
const nextVideo = () => {
  if (selectedVideo.value.equipmentId) {
    // 新增或修改正在查看的巡视记录时间
    addOrEditInspectionRecord()

    // 获取当前视频数据数组下标
    const currCameraIndex = videoList.value.findIndex((item) => { return item.id == selectedVideo.value.equipmentId })
    // 获取下一个在线视频数据，如果没有下一个视频，则返回第一个视频
    const nextCamera = getNextOnlineCamera(currCameraIndex)

    selectedVideo.value = JSON.parse(JSON.stringify(nextCamera))

    // 如果巡视记录中没有当前摄像头，则添加巡视记录
    const nextInspectionRecordCameraIndex = patrolRecordList.value.findIndex((item) => { return item.equipmentId == selectedVideo.value.equipmentId })
    if (nextInspectionRecordCameraIndex == -1) {
      selectedVideo.value.startTime = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
      selectedVideo.value.endTime = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
      selectedVideo.value.patrolDuration = 0
      patrolRecordList.value.push(JSON.parse(JSON.stringify(selectedVideo.value)))
    }

    playVideo()
  } else {
    proxy?.$modal.msgError('请先选择左侧摄像头再开始')
  }
}

/**
 * 获取下一个在线摄像头
 */
const getNextOnlineCamera = (currCameraIndex: number): any => {
  // 判断是否所有摄像头都离线，如果都离线，则返回null
  if (videoList.value.filter((item: any) => item.deviceStatus === 'ONLINE').length === 0) {
    return null;
  }

  // 获取下一个视频数据，如果没有下一个视频，则返回第一个视频
  const nextCameraIndex = (currCameraIndex + 1) % videoList.value.length;
  const nextCamera = videoList.value[nextCameraIndex];

  if (nextCamera.deviceStatus === 'ONLINE') {
    return nextCamera;
  } else {
    return getNextOnlineCamera(nextCameraIndex);
  }
}

/**
 * 打开图片列表弹窗
 */
const imgList = ref([])
const openImgList = (item: any) => {
  dialog.showImgList = true
  imgList.value = item
}

/**
 * 打卡
 */
const checkInLoading = ref(false)
const showCheckIn = ref(false)
const checkIn = async () => {
  const param = {
    cameraPatrolTaskExecutorId: props.cameraPatrolTaskExecutorId,
    clockFlagStatus: 1
  }
  checkInLoading.value = true
  const res = await updatePatrolTaskExecutorClock(param).finally(() => { checkInLoading.value = false })
  if (res.code == 200) {
    proxy?.$modal.msgSuccess('打卡成功')
    showCheckIn.value = false
  } else {
    proxy?.$modal.msgError('打卡失败')
  }
}

/**
 * 获取详情
 */
const patrolTaskExecutor = ref<any>({})
const getInfo = async () => {
  proxy.$modal.loading('加载中...')
  request({
    url: '/camera/patrolTaskExecutor/' + props.cameraPatrolTaskExecutorId,
    method: 'get'
  }).then((res) => {
    console.log('获取详情：', res)

    patrolTaskExecutor.value = res.data

    // 如果任务正进行中，10秒后提示打卡
    if (patrolTaskExecutor.value.status == 1 && patrolTaskExecutor.value.clockFlag == 1 && patrolTaskExecutor.value.clockFlagStatus == 0) {
      setTimeout(() => {
        showCheckIn.value = true

        // 10分钟后关闭提示
        setTimeout(() => {
          showCheckIn.value = false
        }, 10 * 60 * 1000);
      }, 10 * 1000);
    }
  }).finally(() => { proxy.$modal.closeLoading() })
}

/**
 * 完成巡视
 */
const completeTaskLoading = ref(false)
const completeTask = async () => {
  completeTaskLoading.value = true
  proxy.$modal.loading('正在处理')

  // 停止定时器
  clearInterval(timer.value)
  // 上传最新巡视记录
  await addOrEditInspectionRecord()

  request({
    url: '/camera/patrolTaskExecutor/complete',
    method: 'put',
    data: { cameraPatrolTaskExecutorId: props.cameraPatrolTaskExecutorId
    }}).then((res: any)=> {
    if (res.code == 200) {
      proxy?.$modal.msgSuccess('操作成功')
      emit('submit')
      emit('close')
    } else {
      proxy?.$modal.msgError(res.msg)
    }
  }).finally(() => {
    completeTaskLoading.value = false
    proxy.$modal.closeLoading()
  })
}

/**
 * 新增或修改巡视记录
 */
let inspectionRecord = reactive<any>({})
const addOrEditInspectionRecord = async () => {
  if (inspectionRecord.cameraPatrolRouteCameraId) {
    await request({
      url: '/camera/patrolTaskInfoLog/add-or-edit?random=' + Math.floor(1000000000 + Math.random() * 9000000000),
      method: 'put',
      data: {
        random: Math.floor(1000000000 + Math.random() * 9000000000),
        cameraPatrolRouteCameraId: inspectionRecord.cameraPatrolRouteCameraId,
        cameraPatrolTaskExecutorId: patrolTaskExecutor.value.cameraPatrolTaskExecutorId,
        patrolDuration: inspectionRecord.patrolDuration
      }
    })
  }
}

onMounted(() => {
  getInfo()
  getPatrolRouteList(props.cameraPatrolTaskExecutorId)
  getInspectionEventList()
  getPatrolLogList()

  // 计算摄像机巡视时长，任务开始后才开始计时
  let time: number = null
  timer.value = setInterval(() => {
    time = time + 1
    if (patrolTaskExecutor.value.status == 1 && selectedVideo.value.equipmentId) {
      inspectionRecord = patrolRecordList.value.find((item) => { return item.equipmentId == selectedVideo.value.equipmentId })
      if (inspectionRecord) {
        inspectionRecord.patrolDuration = Number(inspectionRecord.patrolDuration) + 1
        inspectionRecord.endTime = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
      }

      // 更新巡视记录时间，每5秒更新一次
      if (time % 5 == 0) {
        addOrEditInspectionRecord()
      }
    }
  }, 1000);
})

onBeforeUnmount(() => {
  if (timer.value) {
    clearInterval(timer.value)
    // 新增或修改正在查看的巡视记录时间
    addOrEditInspectionRecord()
  }
})
</script>
<style lang="scss" scoped>
:deep(.el-card__header) {
  height: 60px;
}
:deep(.el-card__body) {
  height: calc(100% - 60px);
}
:deep(.pagination-container) {
  margin-top: 0;
}
.block {
  width: 5px;
  height: 17px;
  background: #0058f6;
  border-radius: 66px 66px 66px 66px;
  display: inline-block;
  margin-right: 5px;
  vertical-align: middle;
}
.bt {
  font-weight: 500;
  font-size: 14px;
  color: #333333;
  margin-bottom: 10px;
  display: inline-block;
}
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
.http-message {
  z-index: 9999 !important;
  width: 100%;
  height: 100%;
}
</style>
